/**
 * 
 */
package org.t2.game.server.module.player.api;

import java.util.ArrayList;
import java.util.List;

import org.gaming.service.asserts.Asserts;
import org.gaming.tool.GsonUtil;
import org.gaming.tool.LocalDateTimeUtil;
import org.gaming.tool.SortUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.t2.game.server.foundation.player.LogoutInternalMessage;
import org.t2.game.server.foundation.player.PlayerActorPool;
import org.t2.game.server.foundation.player.PlayerContext;
import org.t2.game.server.foundation.player.PlayerContextManager;
import org.t2.game.server.module.bag.model.Bag;
import org.t2.game.server.module.bag.service.BagService;
import org.t2.game.server.module.hero.model.Hero;
import org.t2.game.server.module.hero.service.HeroService;
import org.t2.game.server.module.player.message.PlayerForbidMessage;
import org.t2.game.server.module.player.message.PlayerForbidRankMessage;
import org.t2.game.server.module.player.model.Player;
import org.t2.game.server.module.player.model.PlayerSwitch;
import org.t2.game.server.module.player.service.PlayerService;
import org.t2.game.server.module.player.service.PlayerSwitchService;
import org.t2.game.server.module.tips.TipsCode;

import pb.t2.protobuf.player.Player.PbLogoutType;
import sh.t2.share.apiutil.GameApi;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerDeleteSwitchRequest;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerDeleteSwitchResponse;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerDetailRequest;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerDetailResponse;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerForbidRequest;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerForbidResponse;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerHeroRequest;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerHeroResponse;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerOfflineRequest;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerOfflineResponse;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerSwitchRequest;
import sh.t2.share.module.player.PlayerApiProtocol.PlayerSwitchResponse;
import sh.t2.share.module.player.form.HeroData;
import sh.t2.share.module.player.form.PlayerDetailData;

/**
 * 
 */
@Controller
public class PlayerApi {

	private static Logger logger = LoggerFactory.getLogger(PlayerApi.class);
	
	@Autowired
	private PlayerService playerService;
	@Autowired
	private PlayerContextManager playerContextManager;
	@Autowired
	private BagService bagService;
	@Autowired
	private PlayerSwitchService playerSwitchService;
	@Autowired
	private HeroService heroService;
	
	
	@RequestMapping(value = GameApi.playerDetails)
	@ResponseBody
	public PlayerDetailResponse info(@RequestBody PlayerDetailRequest request) {
		Player player = playerService.getEntity(request.playerId);
		Asserts.isTrue(player != null, TipsCode.PLAYER_NOT_FOUND);
		
		PlayerDetailResponse response = new PlayerDetailResponse();
		response.playerId = player.getId();
		
		PlayerDetailData detail = new PlayerDetailData();
		detail.setId(player.getId());
		detail.setNick(player.getNick());
		detail.setLevel((int)player.getLevel());
		detail.setVipLevel(player.getVipLevel());
		//后台需要显示的单位是元
		detail.setRecharge(player.getRecharge() / 100);
		detail.setBornTime(LocalDateTimeUtil.toEpochMilli(player.getInsertTime()));
		detail.setMission((int)player.getMission());
		
		Bag bag = bagService.getEntity(player.getId());
		detail.setGold(bag.getGold());
		detail.setDiamond(bag.getDiamond());
		detail.setMuscle((int)bag.getMuscle());
		detail.setPoint(bag.getPoint());
		detail.setGooseFeather(bag.getFeather());
		detail.setHeroNum((int)bag.getHeroNum());
		detail.setWeaponSummon((int)bag.getWeaponSummon());
		detail.setWeaponNum((int)bag.getWeaponNum());
		detail.setTreasureSummon((int)bag.getTreasureSummon());
		detail.setTreasureNum((int)bag.getTreasureNum());
		response.detail = detail;
		return response;
	}
	

	@RequestMapping(value = GameApi.playerForbid)
	@ResponseBody
	public PlayerForbidResponse forbid(@RequestBody PlayerForbidRequest request) {
		Player player = playerService.getEntity(request.playerId);
		Asserts.isTrue(player != null, TipsCode.PLAYER_NOT_FOUND);
		
		PlayerActorPool.tell(new PlayerForbidMessage(request.playerId, request.forbidEndTime));
		return new PlayerForbidResponse();
	}
	
	@RequestMapping(value = GameApi.playerForbidRank)
	@ResponseBody
	public PlayerForbidResponse forbidRank(@RequestBody PlayerForbidRequest request) {
		Player player = playerService.getEntity(request.playerId);
		Asserts.isTrue(player != null, TipsCode.PLAYER_NOT_FOUND);
		
		PlayerActorPool.tell(new PlayerForbidRankMessage(request.playerId, request.forbidEndTime));
		return new PlayerForbidResponse();
	}
	
	/**
	 * 强制玩家下线
	 */
	@RequestMapping(value = GameApi.playerForcedOffline)
	@ResponseBody
	public PlayerOfflineResponse forcedOffline(@RequestBody PlayerOfflineRequest request) {
		PlayerContext playerContext = playerContextManager.getContext(request.playerId);
		if(playerContext != null) {
			LogoutInternalMessage message = new LogoutInternalMessage();
			message.playerContext = playerContext;
			message.logoutType = PbLogoutType.FORCE_OFFLINE;
			PlayerActorPool.tell(message);
		}
		return new PlayerOfflineResponse();
	}
	
	@RequestMapping(value = GameApi.playerSwitch)
	@ResponseBody
	public PlayerSwitchResponse playerSwitch(@RequestBody PlayerSwitchRequest request) {
		try {
			PlayerSwitch playerSwitch = new PlayerSwitch();
			playerSwitch.setOriPlayerId(request.oriPlayerId);
			playerSwitch.setDestPlayerId(request.destPlayerId);
			playerSwitchService.insert(playerSwitch);
			
			logger.info("新增账户切换记录" + GsonUtil.toJson(playerSwitch));
			
			PlayerContext playerContext = playerContextManager.getContext(request.destPlayerId);
			if(playerContext != null) {
				LogoutInternalMessage message = new LogoutInternalMessage();
				message.playerContext = playerContext;
				message.logoutType = PbLogoutType.SWITCH_OFFLINE;
				PlayerActorPool.tell(message);
			}
			return new PlayerSwitchResponse();
		} catch (Exception e) {
			Asserts.isTrue(false, TipsCode.PLAYER_SWITCH_ONLY);
			return null;
		}
	}
	
	@RequestMapping(value = GameApi.playerDeleteSwitch)
	@ResponseBody
	public PlayerDeleteSwitchResponse deleteSwitch(@RequestBody PlayerDeleteSwitchRequest request) {
		PlayerSwitch playerSwitch = playerSwitchService.getOriSwitch(request.oriPlayerId);
		logger.info("删除账户切换记录" + GsonUtil.toJson(request));
		if(playerSwitch == null) {
			return new PlayerDeleteSwitchResponse();
		}
		logger.info("删除账户切换记录" + GsonUtil.toJson(playerSwitch));
		playerSwitchService.delete(playerSwitch);
		return new PlayerDeleteSwitchResponse();
	}
	
	@RequestMapping(value = GameApi.playerHeros)
	@ResponseBody
	public PlayerHeroResponse heroDatas(@RequestBody PlayerHeroRequest request) {
		List<Hero> heros = heroService.getEntities(request.playerId);
		
		List<HeroData> heroDatas = new ArrayList<>();
		for(Hero hero : heros) {
			HeroData heroData = new HeroData();
			heroData.setIdentity(hero.getIdentity());
			heroData.setInsertTime(LocalDateTimeUtil.toEpochMilli(hero.getInsertTime()));
			heroDatas.add(heroData);
		}
		SortUtil.sort(heroDatas, HeroData::getInsertTime);
		
		PlayerHeroResponse response = new PlayerHeroResponse();
		response.heroes = heroDatas;
		return response;
	}
}
